#include <stdio.h>
#include <stdlib.h>

typedef struct listNode {
	struct listNode *prev;
	struct listNode *next;
	void *value;
} listNode;

typedef struct list {
	listNode *head;
	listNode *tail;
	unsigned int len;
} list;

typedef struct listIter {
	listNode *next;
} listIter;

list *listCreate() {
	list* list;
   	list = malloc(sizeof(*list));
	if (list == NULL) 
		return NULL;
	list->head = NULL;
	list->tail = NULL;
	list->len = 0;
	return list;
}

void listRelease(list *list) {
	unsigned int len;
	listNode *current, *next;

	current = list->head;
	len = list->len;
	while (len--) {
		next = current->next;
		free(current);
		current = next;
	}
	free(list);
}

list *listAddNodeHead(list *list, void *value) {
	listNode *node;
	if ((node = malloc(sizeof(*node))) == NULL) 
		return NULL;
	node->value = value;
	if (list->len == 0) {
		list->head = node;
		list->tail = node;
		node->prev = node->next = NULL;
	} else {
		node->prev = NULL;
		node->next = list->head;
		list->head->prev = node;
		list->head = node;
	}
	list->len++;
	return list;
}

void listDelNode(list *list, listNode *node) {
	if (node->prev) 
		node->prev->next = node->next;
	else 
		list->head = node->next;
	if (node->next) 
		node->next->prev = node->prev;
	else 
		list->tail = node->prev;
	free(node);
	list->len--;
}

listIter *listGetIterator(list *list) {
	listIter *iter;

	if ((iter = malloc(sizeof(*iter))) == NULL)
		return NULL;
	iter->next = list->head;
	return iter;
}

void listReleaseIterator(listIter *iter) {
	free(iter);
}

listNode *listNextElement(listIter *iter) {
	listNode *current = iter->next;

	if (current == NULL) 
		return NULL;
	iter->next = current->next;
	return current;
}

listNode *listSearchKey(list *list, void *key) {
	listIter *iter;
	listNode *node;

	iter = listGetIterator(list);
	while ((node = listNextElement(iter)) != NULL) {
		if (key == node->value) {
			listReleaseIterator(iter);
			return node;
		}
	}
	listReleaseIterator(iter);
	return NULL;
}

void main() {
	list *l1 = listCreate();
	listAddNodeHead(l1, "sss");
	int i1 = 111;
	listAddNodeHead(l1, &i1);
	int i2 = 222;
	listAddNodeHead(l1, &i2);
	listNode *node; 

	listIter *iter = listGetIterator(l1);
	while ((node = listNextElement(iter)) != NULL) {
		if (&i1 == node->value || &i2 == node->value) 
		   printf("node=%d\n", *((int *)node->value));
		else	
			printf("node=%s\n", node->value);
	}
	listReleaseIterator(iter);

	node = listSearchKey(l1, &i1);
}
